iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 11
0
Modern Web

RRR撞到不負責之 Laravel + Nuxt.js 踩坑全紀錄系列 第 11

Day 11. 第一個 Laravel API 終於生出來惹 (´;ω;`)

  • 分享至 

  • xImage
  •  

在介紹完 controller 之後,接著要為 API 綁定 URL 讓其他系統可以使用。今天會依照下面主題逐一介紹 Laravel Routing 設定。

基本用法

所有的 API 對應的網址都會寫在 routes 底下的檔案中,我們可以依照需求分在不同檔案,但目前我們只依照 Laravel 基本的分類寫在 routes\api.php

所有的方法都是呼叫 \Illuminate\Support\Facades\Route (以下簡稱 Route) 而來,如果 IDE 連結不到原始的類別,可以安裝 barryvdh/laravel-ide-helper 讓開發更簡便。

五個常用的 HTTP 方法 (GETPOSTPUTPATCHDELETE),會是最終、也是最簡單綁定 URL 和 API 方法的功能。這五個方法,第一個參數是自訂義的 URL;第二個參數是閉包或是對應的 controller function (以下稱為 action)。

Route::get('v1/post/view', 'PostController@read');

Route::post('v1/post/create', 'PostController@create');

Route::put('v1/post/update', 'PostController@edit');

Route::patch('v1/post/update/title', 'PostController@editTitle');

Route::delete('v1/post/delete', function (Request $request) {
    // ...
});

從上面的範例可以看到 get()post()put()patch(),我們都是以設定對應 action 方式綁定;delete() 則是使用閉包的方法。如果有一些沒有太多商業邏輯或是極其簡單的資料,也可以直接在閉包裡面處理和回傳 response。

動態參數

我們有時因應需求,會需要在 URL 中間帶上資料,但又不想使用 query string,此時
只要在 URL 中間以 {<變數名稱>} 設定即可。

// api.php:
Route::post('v1/post/{postId}/update', 'PostController@edit');

// PostController.php:
class PostController extends Controller
{
    public function edit($postId, FormRequest $request)
    {
        // ...

例如上面的例子,當我們呼叫 http://.../v1/post/2764/update 時,首先會根據 api.php 的設定執行 PostController 的 edit 方法,同時會將「2764」帶入 $postId 中。只要參數名稱與 route 中設定的一樣,在 action 中的位置順序,不影響資料的帶入。

在一些狀況下,我們要讓參數具有預設值,如同上面的設定,並在變數名稱後面加上「?」 如: {<變數名稱>?} 即可。

// api.php:
Route::post('v1/post/eidt/{title?}', 'PostController@editTitle');

// PostController.php:
class PostController extends Controller
{
    public function editTitle($title = "no title", FormRequest $request)
    {
        // ...

在動態變數中 Laravel 提供方便驗證變數是否合法的方式 where()。第一個參數是變數名稱,第二個參數是驗證變數值的正則表示式;如果一個 URL 有多個變數需要驗證可以改用 array 的方式。

Route::post('v1/post/{postId}/update', 'PostController@edit')->where('postId', '[0-9]+');

route 分組

從一開始五個常用的 HTTP 方法設定範例中我們可以看到每一個 URL 都有共同的部份 v1/post,在 Laravel 中透過分組 (groups) 的寫法,進一步整合管理,減少重複撰寫相同的部份或是共同的設定。以下介紹幾個常用的分組方法,完整介紹請參考官網

  • prefix: 前缀是用來設定 URL 開始共同的部份,如上面 HTTP 方法的範例,我們可以改寫為:
Route::prefix("v1/post")->group(function () {
    Route::get('view', 'PostController@read');
    Route::post('create', 'PostController@create');
    Route::put('update', 'PostController@edit');
    // ...
});
  • namespace: 假若我們要綁定的 controller 不是在預設的 app/Http/Controller 裡面,而是有更進一步的分類,這時候可以設定 namespace() 方便管理。例如我們將 controller 分在 app/Http/Controller/Adminapp/Http/Controller/User 兩個資料夾,我們就可以設計如:
Route::namespace('Admin')->group(function () {
    Route::get('v1/admin/manager/create', 'ManagerController@createManager');
    Route::get('v1/admin/user/{id}/delete', 'ManagerController@delete');
    // ...
});
  • middleware: Middleware 是 Laravel 在進入 action 之前會先對 http request 進行過濾、檢查的地方,這部份我們會在明後天更進一步的說明。在 route 中,我們可以將有共同過濾或檢查機制管理在一起。
Route::middleware('adminonly')->group(function () {
    Route::get('v1/admin/manager/create', 'UserController@createManager');
    Route::get('v1/admin/user/{id}/delete', 'UserController@delete');
    // ...
});

其他設定

所有在 api.php 設定的 routing,完整網址都是由 <domain 或是 IP>/api/.... 組成。我們可以打開 app\Providers\RouteServiceProvider.php,在 mapApiRoutes() 中客製化自己的設定,

    protected function mapApiRoutes()
    {
        Route::prefix('api') // 可以改成自己的 prefix 或是移除,以下類推
             ->middleware('api')
             ->namespace($this->namespace)
             ->group(base_path('routes/api.php')); // 這裡定義了要套用到哪一個設定檔
    }

另外,我們在綁定了 URL 與 action 之後,我們可以使用postman這個很好用的發送 http request 工具,測試我們所寫的 API。

https://ithelp.ithome.com.tw/upload/images/20190912/201125804JGlHlVE5r.png

  1. 我們會先輸入 API 網址,(要記得將 wamp 或是其他伺服器服務啟動)
  2. 如果要在 request 中帶資料,通常我們會使用 JSON 格式資料
  3. 輸入 request body 資料
  4. 送出之後,我們會在下方看到 API 回傳的 response 資料

終於! 到目前為止我們可以用 Laravel 寫出完整的 API 服務,學習曲線個人認為滿舒服的,大家可以試試看! 明天我們將進一步地叫紹 Laravel Middelware 的部分,像上面說的,透過 middlewares 可以讓我們進到 action 之前就先檢查、過濾不合法的 request,例如,一般使用者的身分不得執行或是呼叫管理者的 API 等諸如此類的保護機制!


上一篇
Day 10. FormRequest 管理驗證規則的好幫手
下一篇
Day 12. HiNet 有小天使,Laravel 有 Middleware !
系列文
RRR撞到不負責之 Laravel + Nuxt.js 踩坑全紀錄31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
4a7g0112
iT邦新手 5 級 ‧ 2021-11-21 21:01:02

https://img.onl/maYjZb
最近在學習Laravel 按照著大大步驟慢慢學習
想請問為什麼我得按照的程式碼輸入但是我的路由卻沒有出現五個呢?
是哪個地方出現問題還請指點一下

albert41 iT邦新手 3 級 ‧ 2021-11-23 01:35:21 檢舉

诶斗... 你上傳的圖片失效耶 XD
另外問一下,你是使用哪個版本的 Laravel (我猜是 8.0)?
Day02 裡面有提到當時候這篇是以 5.8 做教學的,金拍謝~ 不過有問題我可以找時間盡量幫看看新版的文件說明~

回到主題,在 8.0 的文件中,Route 的寫法改變了,主要是因為
RouteServiceProvider.php 裡的變數 $namespace 預設改為 null (在之前版本預設會是 'App\Http\Controllers' )。

所以解決方法:

  1. 依照 8.0 的寫法: Route::get('v1/post/view', [PostController::class, 'read']);
  2. $namespace 賦值為 'App\Http\Controllers'

我要留言

立即登入留言